/**
 * Unit test for class Pawn in pieces package
 * Most of the methods that are tested in this unit test are implemented from Piece class
 * 
 * @author Dzulhafizi Abidin
 */

package unitTests;
import pieces.*;
import mainClasses.*;

import junit.framework.TestCase;


public class PawnTest extends TestCase {
	
	//initializations of several pawns on board b with different positions
	Board b = new Board();
	Pawn pawn = new Pawn(1, 2, b, "White");
	Pawn pawn1 = new Pawn(1, 4, b, "White");
	Pawn pawn2 = new Pawn(3, 2, b, "Black");
	Pawn pawn3 = new Pawn(4, 4, b, "White");
	Pawn pawn4 = new Pawn(6, 1, b, "Black");
	Pawn pawn5 = new Pawn(6, 6, b, "Black");
	

	/**
	 * Tests the movePossible() method in Bishop class
	 */
	public void testMovePossible() {
		
		//a list of assertions to confirm the accuracy of the pawns' movement
		assertTrue(pawn.movePossible(2,2));
		assertTrue(pawn1.movePossible(2,4));		
		assertTrue(pawn2.movePossible(2,2));
		assertTrue(pawn3.movePossible(5,4));
		assertTrue(pawn4.movePossible(5,1));
		assertTrue(pawn5.movePossible(5,6));
		
		assertFalse(pawn.movePossible(5,6));
		assertFalse(pawn1.movePossible(5,1));
		assertFalse(pawn2.movePossible(5,4));
		assertFalse(pawn3.movePossible(2,2));
		assertFalse(pawn4.movePossible(2,2));
		assertFalse(pawn5.movePossible(2,4));
		
	}

	/**
	 * Tests the constructor of the Pawn class
	 */
	public void testPawn() {
		assertTrue((pawn.getX() == 1) && (pawn.getY() == 2));	
		assertFalse(pawn.getClass().equals(NullPiece.class) );								
		assertTrue(pawn.getType().equals("  Pawn   "));		
		assertTrue(pawn.getSide().equals("White"));		
	}


	/**
	 * Tests the getX() accessor in Pawn class
	 */
	public void testGetX() {
		assertTrue(pawn.getX() == 1);
		assertTrue(pawn1.getX() == 1);
		assertTrue(pawn2.getX() == 3);
		assertTrue(pawn3.getX() == 4);
		assertTrue(pawn4.getX() == 6);
		assertTrue(pawn5.getX() == 6);
	}

	/**
	 * Tests the getY() accessor in Pawn class
	 */
	public void testGetY() {
		assertTrue(pawn.getY() == 2);
		assertTrue(pawn1.getY() == 4);
		assertTrue(pawn2.getY() == 2);
		assertTrue(pawn3.getY() == 4);
		assertTrue(pawn4.getY() == 1);
		assertTrue(pawn5.getY() == 6);
	}


	/**
	 * Tests the getStatus() accessor in Pawn class
	 */
	public void testGetStatus() {
		assertFalse(pawn.getClass().equals(NullPiece.class) );			//confirms that pawn is not a nullPiece
		assertTrue(pawn1 instanceof Pawn);								//confirms that pawn1 is an instance of Pawn class
	}

	/**
	 * Tests the getType() accessor in Pawn class
	 */
	public void testGetType() {
		assertTrue(pawn.getType().equals("  Pawn   "));		
		assertTrue(pawn1.getType().equals("  Pawn   "));		
		assertTrue(pawn2.getType().equals("BK-->Pawn"));		
		assertTrue(pawn3.getType().equals("  Pawn   "));		
		assertTrue(pawn4.getType().equals("BK-->Pawn"));		
		assertTrue(pawn5.getType().equals("BK-->Pawn"));		
	}

	/**
	 * Tests the getSide() accessor in Pawn class
	 */
	public void testGetSide() {
		assertTrue(pawn.getSide().equals("White"));	
		assertTrue(pawn1.getSide().equals("White"));	
		assertTrue(pawn2.getSide().equals("Black"));	
		assertTrue(pawn3.getSide().equals("White"));	
		assertTrue(pawn4.getSide().equals("Black"));	
		assertTrue(pawn5.getSide().equals("Black"));	
	}

	/**
	 * Tests the setType() mutator in Pawn class
	 */
	public void testSetType() {
		pawn.setType("Green");									//sets the type of pawn to "Green"
		assertTrue(pawn.getType().equals("Green"));				//checks whether the type of pawn has been changed or not
		pawn.setType("  Pawn   ");								//sets back the type of the pawn 
	}

	/**
	 * Tests the isEqual() method in Pawn class
	 */
	public void testIsEqual() {
		Pawn pawnX = new Pawn(1,2,b,"White");					//creates a new instance of Pawn with the same attributes as pawn
		assertTrue(pawn.isEqual(pawnX));						//confirms the equality between the two pawns
	}

	/**
	 * Tests the move() method in Piece class, implemented by Pawn class. The two kings have to be added to 
	 * the board because a feature of the board class doesn't allow any movement on the board if there's no 
	 * king or only one on it. Several different movements are called on the pawns and this test confirms the 
	 * accuracy of the move() method in Piece class.
	 * 
	 * The pawns will only move to the desired Point if it's legal.
	 */
	public void testMove() {
		Board b1 = new Board();
		Pawn newPawn = new Pawn(1, 0, b1, "White");
		Pawn enemyPawn = new Pawn(5, 1, b1, "Black");
		King king1 = new King(0, 3, b1, "White");
		King king2 = new King(7, 4, b1, "Black");
		b1.add(king1);
		b1.add(king2);
		b1.add(newPawn);
		b1.add(enemyPawn);
		b1.print();
			
		newPawn.move(3,0);
		b1.print();
		assertTrue((newPawn.getX() == 3) && (newPawn.getY() == 0));
		
		newPawn.move(1,3);
		assertTrue((newPawn.getX() == 3) && (newPawn.getY() == 0));
		
		enemyPawn.move(4,1);
		assertTrue((enemyPawn.getX() == 4) && (enemyPawn.getY() == 1));
		b1.print();
		
		newPawn.move(4,1);
		assertTrue((newPawn.getX() == 4) && (newPawn.getY() == 1));
		b1.print();
		
		newPawn.move(5,1);
		assertTrue((newPawn.getX() == 5) && (newPawn.getY() == 1));
			
	}
	

	/**
	 * Tests the changePosition() mutator in Pawn class
	 */
	public void testChangePosition() {
		int dest = 7;
		pawn.changePosition(dest,dest);									//changes the position of the pawn
		assertTrue((pawn.getX() == dest) && (pawn.getY() == dest));					//confirms that the position has been changed
		
		pawn.changePosition(1,2);						//puts the pawn back to its origin
	}

}
